# -*- coding: UTF-8 -*-
import gui, tones, wx
from synthDriverHandler import synthDoneSpeaking, DriverSetting, SynthDriver, synthIndexReached
from collections import OrderedDict
from six import string_types
from . import manager, settings
def initMenus():
    global menuHost, settingMenuItem
    # 添加托盘菜单
    tray = gui.mainFrame.sysTrayIcon
    menuHost = tray.preferencesMenu
    settingMenuItem = menuHost.Insert(1, wx.ID_ANY, _(SynthDriver.description + "设置(&V)..."), _("NVDA settings"))
    tray.Bind(wx.EVT_MENU, onSettingMenuItem, settingMenuItem)
def destroyMenus():
    global menuHost, settingMenuItem
    # 销毁菜单
    menuHost.Remove(settingMenuItem)
def onSettingMenuItem(event):
    # 宝盒语音设置对话框
    def show (evt):
        gui.mainFrame._popupSettingsDialog (settings.SettingsDialog)
    wx.CallAfter(show, None)
# compatibility with nvda 2021.1 alpha versions.
try:
    from speech.commands import BreakCommand, CharacterModeCommand, IndexCommand, PitchCommand, RateCommand, VolumeCommand, LangChangeCommand
except ImportError:
    from speech import BreakCommand, CharacterModeCommand, IndexCommand, PitchCommand, RateCommand, VolumeCommand, LangChangeCommand
class SpeedIncreaseSetting(DriverSetting):
    defaultVal: float
    def __init__(self):
        super().__init__("speedincrease", _("语速增强&S"), availableInSettingsRing = True, displayName = pgettext('synth setting', '语速增强'))
        self.defaultVal = 1.0
    def _get_configSpec(self):
        return "float(default={defaultVal})".format(defaultVal=self.defaultVal)
class RdnSetting(DriverSetting):
    defaultVal: int
    def __init__(self):
        super().__init__("rdn", _("数字读法&R"), availableInSettingsRing = True, displayName = pgettext('synth setting', '数字读法'))
        self.defaultVal = 0
    def _get_configSpec(self):
        return "integer(default={defaultVal})".format(defaultVal=self.defaultVal)
class TempoSetting(DriverSetting):
    defaultVal: float = 1.0
    def __init__(self):
        super().__init__("tempo", _("播放倍速&T"), availableInSettingsRing = True, displayName = pgettext('synth setting', '播放倍速'))
        self.defaultVal = 1.0
    def _get_configSpec(self):
        return "float(default={defaultVal})".format(defaultVal=self.defaultVal)
class SynthDriver(SynthDriver):
    @classmethod
    def check(cls):
        return True
    @property
    def supportedSettings (self):
        voiceSetting = SynthDriver.VoiceSetting()
        voiceSetting.defaultVal = 'local-xiaoyan'
        volumeSetting = SynthDriver.VolumeSetting()
        volumeSetting.defaultVal = 100
        return (voiceSetting, TempoSetting(),
        SynthDriver.PitchSetting(), volumeSetting,
        SynthDriver.RateSetting(), SpeedIncreaseSetting(),
        RdnSetting(),
    )
    supportedCommands = {
        IndexCommand,
        CharacterModeCommand,
        BreakCommand,
        PitchCommand,
        RateCommand,
        VolumeCommand
    }
    supportedNotifications = {synthIndexReached, synthDoneSpeaking}
    description = 'NV 宝盒语音合成器'
    name = 'nvbox'
    def __init__(self):
        # 初始化合成器
        self.manager = manager.SynthManager()
    def terminate(self):
        # 释放资源
        self.manager.terminate()
        del self.manager
    def speak(self,speechSequence):
        # 朗读函数
        text = iter(speechSequence)
        defaultPitch = None
        def callback():
            nonlocal defaultPitch
            try:
                item = next(text)
            except StopIteration:
                self._onDoneSpeaking()
                return
            if isinstance(item, string_types):
                if isinstance(defaultPitch, int):
                    self.manager.speak(item, callback, defaultPitch)
                    defaultPitch = None
                    return
                self.manager.speak(item, callback)
            elif isinstance(item, IndexCommand):
                self._onIndexReached(item.index)
                callback()
            elif isinstance(item, CharacterModeCommand):
                callback()
            elif isinstance(item, PitchCommand):
                defaultPitch = item.newValue
                callback()
            elif isinstance(item, BreakCommand):
                callback()
            elif isinstance(item, LangChangeCommand):
                callback()
        callback()
    def pause(self,switch):
        # 暂停函数
        self.manager.pause(switch)
    def _get_rate(self):
        # 获取语速
        return self.manager.getSpeed()
    def _set_rate(self, rate):
        # 设置语速
        self.manager.setSpeed(rate)
    def _get_pitch(self):
        # 获取音高
        return self.manager.getPitch()
    def _set_pitch(self, pitch):
        # 设置音高
        self.manager.setPitch(pitch)
    def _get_volume(self):
        # 获取音量
        return self.manager.getVolume()
    def _set_volume(self, volume):
        # 设置音量
        self.manager.setVolume(volume)
    def cancel(self):
        # 取消合成
        self.manager.stop()
    def _get_availableSpeedincreases(self):
        # 获取所有语速增强
        return OrderedDict(self.manager.getSpeedIncreases())
    def _set_speedincrease(self, speedIncrease):
        # 设置语速增强
        self.manager.setSpeedIncrease(speedIncrease)
    def _get_speedincrease(self):
        # 获取语速增强
        return self.manager.getSpeedIncrease()
    def _get_availableTempos(self):
        # 获取所有播放倍速
        return OrderedDict(self.manager.getTempos())
    def _set_tempo(self, tempo):
        # 设置播放倍速
        self.manager.setTempo(tempo)
    def _get_tempo(self):
        # 获取播放倍速
        return self.manager.getTempo()
    def _get_availableRdns(self):
        # 获取所有数字读法
        return OrderedDict(self.manager.getRdns())
    def _set_rdn(self, value):
        self.manager.setRdn(value)
    def _get_rdn(self):
        # 获取数字读法
        return self.manager.getRdn()
    def _getAvailableVoices(self):
        # 获取所有声音
        return OrderedDict(self.manager.getVoices())
    def _get_voice(self):
        # 获取声音
        return self.manager.getVoice()
    def _set_voice(self, voice):
        # 设置声音
        self.manager.setVoice(voice)
    def _onIndexReached(self, index):
        synthIndexReached.notify(synth=self, index=index)
    def _onDoneSpeaking(self):
        synthDoneSpeaking.notify(synth=self)